package com.windowes.weichang.access;

import com.google.gson.Gson;
import com.windowes.weichang.common.Const;
import com.windowes.weichang.common.ServerResponse;
import com.windowes.weichang.component.redis.RedisService;
import com.windowes.weichang.pojo.WUser;
import com.windowes.weichang.service.ShopService;
import com.windowes.weichang.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;

/***
 *
 * @author: yangqing
 * @email: qing.yang@bangdao-tech.com
 * @createTime: 2018/6/1 上午11:21
 * @description:
 *
 **/
public class AccessInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    UserService userService;

    @Autowired
    RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;
            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
            if (accessLimit == null) {
                return true;
            }
            //用户登录
            WUser user = getUser(request, response);
            if (user == null) {
                render(response, ServerResponse.createByLoginErrorMessage("用户登陆时效已过期,请登录！"));
                return false;
            }
            // 后台人员管理权限
            if (accessLimit.manageUser()) {
                Integer deptId = getDeptId(request, response);
                if (deptId == null) {
                    render(response, ServerResponse.createByLoginErrorMessage("权限不足,需要店铺权限！"));
                    return false;
                }
                UserContext.setDeptId(deptId);
            }

            //店铺权限
            if (accessLimit.shopUser()) {
                Integer shopId = getShopId(request, response);
                if (shopId == null) {
                    render(response, ServerResponse.createByLoginErrorMessage("权限不足,需要店铺权限！"));
                    return false;
                }
                user.setSId(shopId);
            }
            //退出
            if (request.getServletPath() != null && request.getServletPath().contains("loginOff")) {
                String token = getToken(request);
                redisService.deleteByKey(token);
                render(response, ServerResponse.createByLoginErrorMessage("已登出！"));
                return false;
            }
            //限制登录
            Boolean limit = user.getLimitedLogin();
            if (limit) {
                render(response, ServerResponse.createByLoginErrorMessage("权限不足,需要店铺权限！"));
            }
            UserContext.setUser(user);
        }
        return true;
    }

    private WUser getUser(HttpServletRequest request, HttpServletResponse response) {
        String token = getToken(request);
        if (StringUtils.isEmpty(token)) {
            return null;
        }

        return userService.getUserByToken(token).getData();
    }

    private String getToken(HttpServletRequest request) {
        String paramToken = request.getParameter(UserService.COOKI_NAME_TOKEN);
        String cookieToken = getCookieValue(request, UserService.COOKI_NAME_TOKEN);
        if (StringUtils.isEmpty(cookieToken)) {
            cookieToken = request.getHeader(UserService.COOKI_NAME_TOKEN);
        }
        return StringUtils.isEmpty(paramToken) ? cookieToken : paramToken;
    }


    private Integer getDeptId(HttpServletRequest request, HttpServletResponse response) {
        String paramToken = request.getParameter(Const.KEY_DEPTID);
        String cookieToken = getCookieValue(request, Const.KEY_DEPTID);
        if (StringUtils.isEmpty(cookieToken)) {
            cookieToken = request.getHeader(Const.KEY_DEPTID);
        }
        if (StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
            return null;
        }
        String token = StringUtils.isEmpty(paramToken) ? cookieToken : paramToken;
        return Integer.valueOf(token);
    }


    private Integer getShopId(HttpServletRequest request, HttpServletResponse response) {
        String paramToken = request.getParameter(ShopService.SHOP_KEY);
        String cookieToken = getCookieValue(request, ShopService.SHOP_KEY);
        if (StringUtils.isEmpty(cookieToken)) {
            cookieToken = request.getHeader(ShopService.SHOP_KEY);
        }
        if (StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
            return null;
        }
        String token = StringUtils.isEmpty(paramToken) ? cookieToken : paramToken;
        return Integer.valueOf(token);
    }


    private void render(HttpServletResponse response, ServerResponse cm) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        out.write(new Gson().toJson(cm).getBytes("UTF-8"));
        out.flush();
        out.close();
    }


    private String getCookieValue(HttpServletRequest request, String cookiName) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null || cookies.length <= 0) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(cookiName)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}
